
var Textbox_Style1 = cc.Node.extend({
    Node_L:null,
    Node_C:null,
    Node_R:null,
    Node_Texts:null,
    LigneNumber:0,
    Node_Text_Ligne:[],
    Node_Arrow:null,
    
    SizeCenterW:0.0,
    ScaleX:0.0,
    TargetScaleX:0.0,
    StateAfterTargetScale:"",
    TextToDisplay:[],
    LastDisplayLigne:0,
    
    EnterPressed:false,
    EnterKey:false,
    
    //Constructor
    ctor:function () {
        this._super();
        this.scheduleUpdate();

        var tmp = cc.CustomSprite.create("res/TextBox_Style1_L.png");
        tmp.setPosition( cc.p(0,0) );
        this.addChild(tmp);
        this.Node_L = tmp;
        
        tmp = cc.CustomSprite.create("res/TextBox_Style1_C.png");
        this.SizeCenterW = 350;
        tmp.setPosition( cc.p(10,0) );
        this.addChild(tmp);
        this.Node_C = tmp;

        
        tmp = cc.CustomSprite.create("res/TextBox_Style1_R.png");
        tmp.setPosition( cc.p(10 + this.SizeCenterW,0) );
        this.addChild(tmp);        
        this.Node_R = tmp;
        
        
        // arrow
        tmp = cc.CustomSprite.create("res/Arrow.png");
        tmp.setPosition( cc.p(330,-8) );
        this.Node_C.addChild(tmp);
        this.Node_Arrow = tmp;
        
        var actionBy = cc.MoveBy.create(0.4, cc.p(0, -8));
        var actionBy2 = actionBy.reverse();
        var seq = cc.Sequence.create(actionBy, actionBy2);
        var repeat = cc.RepeatForever.create(seq);
        
        this.Node_Arrow.runAction(repeat);
        this.Node_Arrow.setVisible(false);
        
        
        // texts
        
        this.Node_Texts = cc.Node.create();
        this.Node_C.addChild( this.Node_Texts );
        
        
        var TextSize = 18;
        var XOffset = 5;
        
        // Ligne 1
        var Text_Ligne = cc.LabelTTF.create("Ligne 1", "Arial", TextSize);
        Text_Ligne.setAnchorPoint(cc.p(0,0));
        Text_Ligne.setPosition(cc.p(XOffset,70));
        Text_Ligne.setColor( cc.c3b(0,0,0) );
        
        this.Node_Text_Ligne[ this.LigneNumber ] =  Text_Ligne;
        this.LigneNumber++;

        
        
        // Ligne 2
        Text_Ligne = cc.LabelTTF.create("Ligne 2", "Arial", TextSize);
        Text_Ligne.setAnchorPoint(cc.p(0,0));
        Text_Ligne.setPosition(cc.p(XOffset,40));
        Text_Ligne.setColor( cc.c3b(0,0,0) );
        
        this.Node_Text_Ligne[ this.LigneNumber ] =  Text_Ligne;
        this.LigneNumber++;
        
        // Ligne 3
        Text_Ligne = cc.LabelTTF.create("Ligne 3", "Arial", TextSize);
        Text_Ligne.setAnchorPoint(cc.p(0,0));
        Text_Ligne.setPosition(cc.p(XOffset,10));
        Text_Ligne.setColor( cc.c3b(0,0,0) );
        
        this.Node_Text_Ligne[ this.LigneNumber ] =  Text_Ligne;
        this.LigneNumber++;

        for(var i=0; i<this.LigneNumber; i++)
        {
            this.Node_Text_Ligne[ i ].setVisible(false);
            this.Node_Texts.addChild( this.Node_Text_Ligne[ i ] );
        }
        
        // init first scale 
        this.Node_Texts.setVisible(false);
        this.ScaleX = 0.0;
        this.resfreshPosition();
        
        this.initFSM();
    },
    
    setTextToShow:function( txt ){
        var TextSize = 18;
        var TextTmp = cc.LabelTTF.create("Ligne 1", "Arial", TextSize);
        TextTmp.setAnchorPoint(cc.p(0,0));
        
        
        var LigneValidate = "";
        var LigneToValidate = "";
        var ActualLigneIndex = 0;

        var strSize = txt.length;
        var ActualCharIndex = 0;
        var last_char = txt.charAt(ActualCharIndex);
        
        while( ActualCharIndex <= strSize-1 )
        {
            last_char = txt.charAt(ActualCharIndex);
            
            LigneToValidate += last_char;
            
            if( last_char == ' ' || last_char == '.' || last_char == ',' ||
                last_char == '?' || last_char == '!' || last_char == ':' ||
                last_char == ';' )
            {
                TextTmp.setString( LigneValidate + LigneToValidate );
                
                if( TextTmp.getContentSize().width <  this.SizeCenterW )
                {
                    LigneValidate += LigneToValidate;
                    LigneToValidate = "";
                }
                else
                {
                    this.TextToDisplay[ ActualLigneIndex ] = LigneValidate;
                    ActualLigneIndex++;
                    
                    LigneValidate = "";
                    LigneValidate += LigneToValidate;
                    LigneToValidate = "";
                }
            }
            
            ActualCharIndex++;
        }
        
        this.TextToDisplay[ ActualLigneIndex ] = LigneValidate + LigneToValidate;
    },
    
    resfreshPosition:function(){        
        this.Node_C.setScale( this.ScaleX,1.0 );
        this.Node_R.setPosition( cc.p(10 + this.SizeCenterW*this.ScaleX,0) );
    },
    
    update:function(dt){
        
        this.updateFSM(dt);
        this.resetKey();
    },
    
    hideAllLignes:function(){
        
        for(var i=0; i<this.LigneNumber; i++)
        {
            this.Node_Text_Ligne[ i ].setString("");
            this.Node_Text_Ligne[ i ].setVisible(false);
        }
    },
    
    
    handleKeyDown:function(e){
        if(e === cc.KEY.enter)
        {
            if( this.EnterKey == false )
                this.EnterPressed = true;
                
            this.EnterKey = true;
        }
    },
    handleKeyUp:function(e){
        if(e === cc.KEY.enter)
        {
            this.EnterKey = false;
        }
    },
    resetKey:function(){
        this.EnterPressed = false;
    },
    handleTouch:function(touchLocation){
    },
    handleTouchMove:function(touchLocation){
    },
    
    
    // Internal FSM
    FSM:null,
    initFSM:function(){
        this.FSM = new FSM( this );
        
        
        this.FSM.DefineState( {
        
            Entry:{
                NeedTransition:function(){
                    if( this.ActiveTime > 1.0 )
                    {
                        this.Target.TargetScaleX = 1.0;
                        this.Target.StateAfterTargetScale = 'ShowText'; 
                        this.GoTo = 'GoToTargetScaleAnim'; 
                        return true;
                    }
                    return false;
                },
            },
            
            Finish:{
                OnEnter:function(){
                    console.log("enter in state finish");
                    this.Target.Node_Texts.setVisible(false);
                    this.Target.Node_Arrow.setVisible(false);
                },
            },
            
            WaitNextText:{
                OnEnter:function(){
                    this.Target.Node_Texts.setVisible(true);
                    this.Target.Node_Arrow.setVisible(true);
                },
                OnExit:function(){
                    this.Target.Node_Texts.setVisible(false);
                    this.Target.Node_Arrow.setVisible(false);
                },
                NeedTransition:function(){
                    if( this.Target.EnterPressed )
                    {
                        if( this.Target.LastDisplayLigne < this.Target.TextToDisplay.length )
                        {
                            this.GoTo = 'ShowText'; 
                            return true;
                        }
                        else
                        {
                            this.Target.TargetScaleX = 0.0;
                            this.Target.StateAfterTargetScale = 'Finish'; 
                            this.GoTo = 'GoToTargetScaleAnim'; 
                            return true;
                        
                            /*this.GoTo = 'Finish'; 
                            return true;*/
                        }
                    }
                    
                    return false;
                },
            },
            
            ShowText:{
                OnEnter:function(){
                    this.isFinish = false;
                    this.Timer = 0.0;
                    this.LogicalLigneIndex = this.Target.LastDisplayLigne;
                    this.VisualLigneIndex = 0;
                    this.ActualCharIndex = 0;
                    
                    this.Target.hideAllLignes();
                    
                    this.Target.Node_Texts.setVisible(true);
                },
                OnUpdate:function(dt){
                    var speed = 0.05;
                    this.Timer += dt;
                    if( this.Timer > speed )
                    {
                        this.Timer = 0.0;
                        
                        if( this.Target.TextToDisplay[ this.LogicalLigneIndex ].length > this.ActualCharIndex )
                        {
                            this.ActualCharIndex++;
                            
                            this.Target.Node_Text_Ligne[this.VisualLigneIndex].setVisible(true);
                            this.Target.Node_Text_Ligne[this.VisualLigneIndex].setString( 
                                this.Target.TextToDisplay[ this.LogicalLigneIndex ].substring(0,this.ActualCharIndex)
                            );
                        }
                        else
                        {
                            if( this.VisualLigneIndex < this.Target.LigneNumber-1 &&
                                this.LogicalLigneIndex < this.Target.TextToDisplay.length-1
                                )
                            { // a free ligne and more data, so increase all index
                                this.VisualLigneIndex++;
                                this.LogicalLigneIndex++;
                                this.ActualCharIndex = 0;
                            }
                            else
                            {
                                // finish
                                this.LogicalLigneIndex++;
                                this.isFinish = true;
                            }
                        }
                    }                    
                },
                NeedTransition:function(){
                    if(this.isFinish)
                    {
                        this.GoTo = 'WaitNextText'; 
                        this.Target.LastDisplayLigne = this.LogicalLigneIndex;
                        return true;
                    }
                    else if( this.Target.EnterPressed )
                    {
                        while(!this.isFinish)
                        {
                            this._OnUpdate(10);
                        }
                        
                        this.GoTo = 'WaitNextText'; 
                        this.Target.LastDisplayLigne = this.LogicalLigneIndex;
                        return true;
                    }
                    return false;
                },
            },
            
            GoToTargetScaleAnim:{
                OnEnter:function(){
                    this.isFinish = false;
                },
                OnUpdate:function(dt){
                    var speed = 5.0;
        
                    if( this.Target.ScaleX != this.Target.TargetScaleX )
                        this.Target.ScaleX = (this.Target.ScaleX < this.Target.TargetScaleX) ? this.Target.ScaleX + speed*dt : this.Target.ScaleX - speed*dt;
                    
                    if( this.Target.ScaleX > this.Target.TargetScaleX - 0.01 && this.Target.ScaleX < this.Target.TargetScaleX + 0.01)
                    {
                        this.Target.ScaleX = this.Target.TargetScaleX;
                        this.isFinish = true;
                    }
                    
                    this.Target.resfreshPosition();
                },
                NeedTransition:function(){
                    if(this.isFinish)
                    {
                        this.GoTo = this.Target.StateAfterTargetScale;
                        return true;
                    }
                    return false;
                },
            },
        } );
        
        // dump states
        this.FSM.StartWithState( "Entry" );
    },
    
    updateFSM:function(dt){
        this.FSM.Update(dt);
    },
});

Textbox_Style1.create = function (/*Multiple Arguments*/) {
    return new Textbox_Style1();
};